home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / clarion / cw15 / tpw15.z / RELATION.TPW < prev    next >
Text File  |  1995-08-29  |  24KB  |  733 lines

  1. #!----------------------------------------------------------------------
  2. #! The RIGather group gathers the Referential Integrity (RI) symbols.
  3. #!
  4. #! We start with the assumption that every file declared for use in AppGen
  5. #! can be used for either record update or delete.  This assumption is
  6. #! made because it is possible that developers will want to code their
  7. #! to perform these action in their own code.
  8. #!
  9. #! %UpdateRelationPrimary and %UpdateRelationSecondary keep all of the
  10. #! relations with update constraints used in the application.
  11. #!
  12. #! %UpdateAttachedFile is a complete list of files used in the RI update
  13. #! for each file used in the AppGen process
  14. #!
  15. #! %DeleteRelationPrimary and %DeleteRelationSecondary keep all of the
  16. #! relations with delete constraints used in the application.
  17. #!
  18. #! %DeleteAttachedFile is a complete list of files used in the RI delete
  19. #! for each file used in the AppGen process
  20. #!----------------------------------------------------------------------
  21. #GROUP(%RIGather)
  22. #FOR(%UsedFile)
  23.   #ADD(%UpdateRelationPrimary,%UsedFile)
  24.   #ADD(%DeleteRelationPrimary,%UsedFile)
  25.   #INSERT(%RIGatherUpdateRelations,%UsedFile)
  26.   #INSERT(%RIGatherDeleteRelations,%UsedFile)
  27. #ENDFOR
  28. #FOR(%UsedFile)
  29.   #ADD(%AllFile,%UsedFile)
  30.   #FOR(%UpdateAttachedFile)
  31.     #ADD(%AllFile,%UpdateAttachedFile)
  32.   #ENDFOR
  33.   #FOR(%DeleteAttachedFile)
  34.     #ADD(%AllFile,%DeleteAttachedFile)
  35.   #ENDFOR
  36. #ENDFOR
  37. #FOR(%AllFile)
  38.   #ADD(%UsedFile,%AllFile)
  39. #ENDFOR
  40. #!----------------------------------------------------------------------
  41. #GROUP(%RIGatherUpdateRelations,%CurrentPrimary)
  42. #FIX(%File,%CurrentPrimary)
  43. #FOR(%Relation),WHERE(%FileRelationType='1:MANY')
  44.   #IF(%RelationConstraintUpdate AND %RelationConstraintUpdate<>'NONE')
  45.     #ADD(%UpdateAttachedFile,%Relation)
  46.     #ADD(%UpdateRelationPrimary,%File)
  47.     #FIX(%UpdateRelationSecondary,%Relation)
  48.     #IF(NOT %UpdateRelationSecondary)
  49.       #ADD(%UpdateRelationSecondary,%Relation)
  50.       #IF(%RelationConstraintUpdate<>'RESTRICT')
  51.         #INSERT(%RIGatherUpdateRelations,%Relation)
  52.       #ENDIF
  53.     #ENDIF
  54.   #ENDIF
  55. #ENDFOR
  56. #!----------------------------------------------------------------------
  57. #GROUP(%RIGatherDeleteRelations,%CurrentPrimary)
  58. #FIX(%File,%CurrentPrimary)
  59. #FOR(%Relation),WHERE(%FileRelationType='1:MANY')
  60.   #IF(%RelationConstraintDelete AND %RelationConstraintDelete<>'NONE')
  61.     #ADD(%DeleteAttachedFile,%Relation)
  62.     #ADD(%DeleteRelationPrimary,%File)
  63.     #FIX(%DeleteRelationSecondary,%Relation)
  64.     #IF(NOT %DeleteRelationSecondary)
  65.       #ADD(%DeleteRelationSecondary,%Relation)
  66.       #IF(%RelationConstraintDelete='CASCADE')
  67.         #INSERT(%RIGatherDeleteRelations,%Relation)
  68.       #ELSIF(%RelationConstraintDelete='CLEAR')
  69.         #INSERT(%RIGatherDeleteClearRelations,%Relation)
  70.       #ENDIF
  71.     #ENDIF
  72.   #ENDIF
  73. #ENDFOR
  74. #!----------------------------------------------------------------------
  75. #GROUP(%RIGatherDeleteClearRelations,%CurrentPrimary)
  76. #FIX(%File,%CurrentPrimary)
  77. #FOR(%Relation),WHERE(%FileRelationType='1:MANY')
  78.   #IF(%RelationConstraintUpdate AND %RelationConstraintUpdate<>'NONE')
  79.     #ADD(%DeleteAttachedFile,%Relation)
  80.     #ADD(%UpdateRelationPrimary,%File)
  81.     #FIX(%UpdateRelationSecondary,%Relation)
  82.     #IF(NOT %UpdateRelationSecondary)
  83.       #ADD(%UpdateRelationSecondary,%Relation)
  84.       #IF(%RelationConstraintUpdate='CASCADE')
  85.         #INSERT(%RIGatherDeleteClearRelations,%Relation)
  86.       #ENDIF
  87.     #ENDIF
  88.   #ENDIF
  89. #ENDFOR
  90. #!----------------------------------------------------------------------
  91. #! The RIDeclare group declares the Referential Integrity (RI) functions.
  92. #! The RICode group writes the actual RI functions.
  93. #!
  94. #! For every file declared for use in AppGen, we declare a function for
  95. #! update and a function for delete.
  96. #!
  97. #! Update functions are named RIUpdate:%File, where %File is the label
  98. #! of the file being updated.  The single parameter for these update
  99. #! functions is the record buffer of the record being updated as it
  100. #! was before the update took place.  This record buffer is used to
  101. #! establish a starting point for RI updates.
  102. #!
  103. #! Delete functions are named RIDelete:%File, where %File is the label
  104. #! of the file being deleted.  There are no parameters for RI delete
  105. #! functions.
  106. #!
  107. #! For every constrained update relation we write a single function.
  108. #! These functions are named RIUpdate:%File:%Relation, where %File is
  109. #! the label of the "1" side (parent) of a 1:MANY, and %Relation is the
  110. #! label of the "MANY" side (child).  The parameter(s) for these relation
  111. #! update functions are the values of the fields of the relation key of
  112. #! the child file which directly link to fields in the relation key of
  113. #! the parent file, as they (the key values) were before the update.
  114. #!
  115. #! For every constrained delete relation we write a single function.
  116. #! These functions are named RIDelete:%File:%Relation, where %File is
  117. #! the label of the "1" side (parent) of a 1:MANY, and %Relation is the
  118. #! label of the "MANY" side (child).  There are no parameters for these
  119. #! functions.
  120. #!
  121. #! All RI functions return a value of 1 if the function fails, and a
  122. #! value of 0 is the function completes normally.
  123. #!----------------------------------------------------------------------
  124. #GROUP(%RIDeclare,%RIGenLocation)
  125. #DECLARE(%RIParameters)
  126. #IF(%RIGenLocation = 'UPDATE')
  127.   #FOR(%UsedFile)
  128.     #FIX(%File,%UsedFile)
  129.     #FIX(%UpdateRelationPrimary,%UsedFile)
  130.     #IF(%UpdateRelationPrimary)
  131. RIUpdate:%UsedFile,LONG
  132. RISnap:%UsedFile
  133.     #ENDIF
  134.   #ENDFOR
  135.   #FOR(%UpdateRelationPrimary)
  136.     #FOR(%UpdateRelationSecondary)
  137.       #FIX(%File,%UpdateRelationPrimary)
  138.       #FIX(%Relation,%UpdateRelationSecondary)
  139. RIUpdate:%File:%Relation,LONG
  140.     #ENDFOR
  141.   #ENDFOR
  142. #ELSIF(%RIGenLocation = 'DELETE')
  143.   #FOR(%UsedFile)
  144.     #FIX(%File,%UsedFile)
  145.     #FIX(%DeleteRelationPrimary,%UsedFile)
  146.     #IF(%DeleteRelationPrimary)
  147. RIDelete:%UsedFile,LONG
  148.     #ENDIF
  149.   #ENDFOR
  150.   #FOR(%DeleteRelationPrimary)
  151.     #FOR(%DeleteRelationSecondary)
  152.       #FIX(%File,%DeleteRelationPrimary)
  153.       #FIX(%Relation,%DeleteRelationSecondary)
  154. RIDelete:%File:%Relation,LONG,PRIVATE
  155.     #ENDFOR
  156.   #ENDFOR
  157. #ENDIF
  158. #!----------------------------------------------------------------------
  159. #GROUP(%GenerateRICode),AUTO
  160. #CREATE(%BuildFile)
  161. #MESSAGE('Generating Module:    ' & %RIUpdFileName, 1) #! Post generation message
  162. #MESSAGE('Generating Referential Update Code',2)
  163. #MESSAGE('',3)
  164.                      MEMBER('%Program')
  165. #DECLARE(%LinkedFields),UNIQUE
  166. #FOR ( %UpdateRelationPrimary )
  167.   #FIX( %File, %UpdateRelationPrimary )
  168.   #FOR( %UpdateRelationSecondary )
  169.     #FIX( %Relation, %UpdateRelationSecondary )
  170.     #FOR ( %FileKeyField ), WHERE(%FileKeyField)
  171.       #ADD(%LinkedFields,%FileKeyField)
  172.     #ENDFOR
  173.   #ENDFOR
  174. #ENDFOR
  175. #IF ( ITEMS(%LinkedFields) )
  176. Snap                 GROUP,THREAD,PRE
  177.   #FOR( %LinkedFields )
  178.     #FIX(%Field,%LinkedFields)
  179.     #IF(%FieldType = 'GROUP')
  180. Sav:%[22]LinkedFields LIKE(%LinkedFields),PRE(SAV)
  181.     #ELSE
  182. Sav:%[22]LinkedFields LIKE(%LinkedFields)
  183.     #ENDIF
  184.   #ENDFOR
  185.                      END
  186. #ENDIF
  187.  
  188. #FOR(%UsedFile)
  189.   #FIX(%UpdateRelationPrimary,%UsedFile)
  190.   #IF(%UpdateRelationPrimary)
  191.     #FIX(%File,%UpdateRelationPrimary)
  192.  
  193. !--------------------------------------------------
  194. RISnap:%[11]UsedFile  PROCEDURE
  195.   CODE
  196.     #FREE(%LinkedFields)
  197.     #FOR (%UpdateRelationSecondary)
  198.       #FIX( %Relation, %UpdateRelationSecondary )
  199.       #FOR ( %FileKeyField ),WHERE( %FileKeyField )
  200.         #ADD(%LinkedFields,%FileKeyField)
  201.       #ENDFOR
  202.     #ENDFOR
  203.     #FOR (%LinkedFields)
  204.   Sav:%LinkedFields = %LinkedFields
  205.     #ENDFOR
  206. #INSERT(%RIWritePrimaryUpdateFunction,%UsedFile)
  207.   #ENDIF
  208. #ENDFOR
  209. #FOR(%UpdateRelationPrimary)
  210.   #FOR(%UpdateRelationSecondary)
  211. #INSERT(%RIWriteSecondaryUpdateFunction,%UpdateRelationPrimary,%UpdateRelationSecondary)
  212.   #ENDFOR
  213. #ENDFOR
  214. #CLOSE(%BuildFile)
  215. #REPLACE(%RIUpdFileName,%BuildFile)
  216. #CREATE(%BuildFile)
  217. #MESSAGE('Generating Module:    ' & %RIDelFileName, 1) #! Post generation message
  218. #MESSAGE('Generating Referential Delete Code',2)
  219. #MESSAGE('',3)
  220.                      MEMBER('%Program')
  221.  
  222. #FOR(%UsedFile)
  223.   #FIX(%DeleteRelationPrimary,%UsedFile)
  224.   #IF(%DeleteRelationPrimary)
  225. #INSERT(%RIWritePrimaryDeleteFunction,%UsedFile)
  226.   #ENDIF
  227. #ENDFOR
  228. #FOR(%DeleteRelationPrimary)
  229.   #FOR(%DeleteRelationSecondary)
  230. #INSERT(%RIWriteSecondaryDeleteFunction,%DeleteRelationPrimary,%DeleteRelationSecondary)
  231.   #ENDFOR
  232. #ENDFOR
  233. #CLOSE(%BuildFile)
  234. #REPLACE(%RIDelFileName,%BuildFile)
  235. #!----------------------------------------------------------------------
  236. #GROUP(%RIWritePrimaryUpdateFunction,%CurrentPrimary)
  237. #DECLARE(%LogoutDesired)
  238. #DECLARE(%LogoutAllowed)
  239. #DECLARE(%PrimaryDriver)
  240. #DECLARE(%LogoutParameters)
  241. #DECLARE(%ElementCount)
  242. #DECLARE(%ProcessedElements)
  243. #DECLARE(%RIParameters)
  244. #DECLARE(%SaveName)
  245. #DECLARE(%PrimaryPrefix)
  246. #FIX(%File,%CurrentPrimary)
  247. #SET(%SaveName,'Sav:'&%FilePrefix)
  248. #SET(%PrimaryPrefix,%FilePrefix)
  249. #SET(%LogoutDesired,%False)
  250. #IF(%OverrideRILogout = 'Use Default' OR NOT %OverrideRILogout)
  251.   #IF(%DefaultRILogout)
  252.     #SET(%LogoutDesired,%True)
  253.   #ENDIF
  254. #ELSIF(%OverrideRILogout = 'Yes')
  255.   #SET(%LogoutDesired,%True)
  256. #ENDIF
  257. #IF(%LogoutDesired)
  258.   #SET(%PrimaryDriver,%FileDriver)
  259.   #FIX(%Driver,%FileDriver)
  260.   #FIX(%DriverOpCode,'LOGOUT')
  261.   #IF(%DriverOpCode)
  262.     #SET(%LogoutParameters,'2,' & %File)
  263.     #FOR(%UpdateAttachedFile)
  264.       #FIX(%File,%UpdateAttachedFile)
  265.       #IF(%OverrideRILogout = 'No')
  266.         #SET(%LogoutDesired,%False)
  267.         #BREAK
  268.       #ELSIF(%FileDriver <> %PrimaryDriver)
  269.         #SET(%LogoutDesired,%False)
  270.         #IF(%WarnOnLogoutError)
  271.           #ERROR('Error writing Update LOGOUT code for ' & %CurrentPrimary & '.  File Driver for ' & %File & ' does not match.')
  272.         #ENDIF
  273.         #BREAK
  274.       #ENDIF
  275.       #SET(%LogoutParameters,%LogoutParameters & ',' & %File)
  276.     #ENDFOR
  277.   #ELSE
  278.     #SET(%LogoutDesired,%False)
  279.   #ENDIF
  280. #ENDIF
  281. #FIX(%File,%CurrentPrimary)
  282. #MESSAGE('Generating RIUpdate' & %File,3)
  283.  
  284. !--------------------------------------------------
  285. RIUpdate:%[11]File FUNCTION
  286.   CODE
  287.   #FOR(%UpdateAttachedFile)
  288.   #INSERT(%FileControlOpenFile,%UpdateAttachedFile)
  289.   #ENDFOR
  290.   #IF(%LogoutDesired)
  291.   LOGOUT(%LogoutParameters)
  292.   IF ERRORCODE()
  293.     StandardWarning(Warn:LogoutError,'Update','%CurrentPrimary')
  294.   #IF(%LogoutDesired)
  295.     ROLLBACK
  296.   #ENDIF
  297.     DO RICloseFiles
  298.     RETURN(1)
  299.   END
  300.   #ENDIF
  301.   #FIX(%File,%CurrentPrimary)
  302.   PUT(%CurrentPrimary)
  303.   IF ERRORCODE()
  304.     IF ERRORCODE() = RecordChangedErr THEN
  305.       StandardWarning(Warn:RIUpdateError,'Record Changed by Another Station')
  306.     ELSE
  307.       StandardWarning(Warn:RIUpdateError,'%CurrentPrimary')
  308.     END
  309.   #IF(%LogoutDesired)
  310.     ROLLBACK
  311.   #ENDIF
  312.     DO RICloseFiles
  313.     RETURN(1)
  314.   END
  315.   #FIX(%UpdateRelationPrimary,%CurrentPrimary)
  316.   #FOR(%UpdateRelationSecondary)
  317.     #FIX(%File,%UpdateRelationPrimary)
  318.     #FIX(%Relation,%UpdateRelationSecondary)
  319.     #SET(%ElementCount,0)
  320.     #FOR(%FileKeyField),WHERE(%FileKeyField)
  321.       #SET(%ElementCount,%ElementCount+1)
  322.     #ENDFOR
  323.     #SET(%ProcessedElements,0)
  324.     #FOR(%FileKeyField),WHERE(%FileKeyField)
  325.       #FIX(%Field,%FileKeyField)
  326.       #SET(%ProcessedElements,%ProcessedElements+1)
  327.       #IF(%ElementCount = 1)
  328.   IF %SaveName:%FieldID <> %PrimaryPrefix:%FieldID
  329.       #ELSIF(%ProcessedElements = 1)
  330.   IF %SaveName:%FieldID <> %PrimaryPrefix:%FieldID |
  331.       #ELSIF(%ElementCount = %ProcessedElements)
  332.   OR %SaveName:%FieldID <> %PrimaryPrefix:%FieldID
  333.       #ELSE
  334.   OR %SaveName:%FieldID <> %PrimaryPrefix:%FieldID |
  335.       #ENDIF
  336.     #ENDFOR
  337.     IF RIUpdate:%File:%Relation()
  338.   #IF(%LogoutDesired)
  339.       ROLLBACK
  340.   #ENDIF
  341.   #FOR(%RelationKeyField)
  342.     #IF(%RelationKeyField)
  343.       %RelationKeyField = %RelationKeyFieldLink
  344.     #ENDIF
  345.   #ENDFOR
  346.       DO RICloseFiles
  347.       RETURN(1)
  348.     END
  349.   END
  350.   #ENDFOR
  351.   #IF(%LogoutDesired)
  352.   COMMIT
  353.   #ENDIF
  354.   DO RICloseFiles
  355.   RETURN(0)
  356. !----------------------------------------------------------------------
  357. RICloseFiles ROUTINE
  358.   #FOR(%UpdateAttachedFile)
  359.   #INSERT(%FileControlCloseFile,%UpdateAttachedFile)
  360.   #ENDFOR
  361.   EXIT
  362. #!----------------------------------------------------------------------
  363. #GROUP(%RIWritePrimaryDeleteFunction,%CurrentPrimary)
  364. #DECLARE(%LogoutDesired)
  365. #DECLARE(%LogoutAllowed)
  366. #DECLARE(%PrimaryDriver)
  367. #DECLARE(%LogoutParameters)
  368. #DECLARE(%RegetParameter)
  369. #FIX(%File,%CurrentPrimary)
  370. #SET(%LogoutDesired,%False)
  371. #IF(%OverrideRILogout = 'Use Default' OR NOT %OverrideRILogout)
  372.   #IF(%DefaultRILogout)
  373.     #SET(%LogoutDesired,%True)
  374.   #ENDIF
  375. #ELSIF(%OverrideRILogout = 'Yes')
  376.   #SET(%LogoutDesired,%True)
  377. #ENDIF
  378. #IF(%LogoutDesired)
  379.   #SET(%PrimaryDriver,%FileDriver)
  380.   #FIX(%Driver,%FileDriver)
  381.   #FIX(%DriverOpCode,'LOGOUT')
  382.   #IF(%DriverOpCode)
  383.     #SET(%LogoutParameters,'2,' & %File)
  384.     #FOR(%DeleteAttachedFile)
  385.       #FIX(%File,%DeleteAttachedFile)
  386.       #IF(%OverrideRILogout = 'No')
  387.         #SET(%LogoutDesired,%False)
  388.         #BREAK
  389.       #ELSIF(%FileDriver <> %PrimaryDriver)
  390.         #SET(%LogoutDesired,%False)
  391.         #IF(%WarnOnLogoutError)
  392.           #ERROR('Error writing Update LOGOUT code for ' & %CurrentPrimary & '.  File Driver for ' & %File & ' does not match.')
  393.         #ENDIF
  394.         #BREAK
  395.       #ENDIF
  396.       #SET(%LogoutParameters,%LogoutParameters & ',' & %File)
  397.     #ENDFOR
  398.   #ELSE
  399.     #SET(%LogoutDesired,%False)
  400.   #ENDIF
  401. #ENDIF
  402. #FIX(%File,%CurrentPrimary)
  403. #MESSAGE('Generating RIDelete' & %File,3)
  404.  
  405. !--------------------------------------------------
  406. RIDelete:%[11]File FUNCTION
  407. Current:Position     STRING(512)
  408.   CODE
  409.   #SET(%RegetParameter,%Null)
  410.   #FOR(%Key),WHERE(EXTRACT(%KeyStruct,'PRIMARY'))
  411.     #SET(%RegetParameter,%Key)
  412.   #ENDFOR
  413.   #IF(NOT(%RegetParameter))
  414.     #FOR(%Key)
  415.       #SET(%RegetParameter,%Key)
  416.       #BREAK
  417.     #ENDFOR
  418.   #ENDIF
  419.   #IF(NOT(%RegetParameter))
  420.     #SET(%RegetParameter,%File)
  421.   #ENDIF
  422.   Current:Position = POSITION(%RegetParameter)
  423.   #FOR(%DeleteAttachedFile)
  424.   #INSERT(%FileControlOpenFile,%DeleteAttachedFile)
  425.   #ENDFOR
  426.   #IF(%LogoutDesired)
  427.   LOGOUT(%LogoutParameters)
  428.   IF ERRORCODE()
  429.     StandardWarning(Warn:LogoutError,'Delete','%CurrentPrimary')
  430.   #IF(%LogoutDesired)
  431.     ROLLBACK
  432.   #ENDIF
  433.     DO RICloseFiles
  434.     RETURN(1)
  435.   END
  436.   #ENDIF
  437.   #FIX(%File,%CurrentPrimary)
  438.   REGET(%RegetParameter,Current:Position)
  439.   #FIX(%DeleteRelationPrimary,%CurrentPrimary)
  440.   #FOR(%DeleteRelationSecondary)
  441.   IF RIDelete:%DeleteRelationPrimary:%DeleteRelationSecondary()
  442.   #IF(%LogoutDesired)
  443.     ROLLBACK
  444.   #ENDIF
  445.     DO RICloseFiles
  446.     RETURN(1)
  447.   END
  448.   #ENDFOR
  449.   DELETE(%CurrentPrimary)
  450.   IF ERRORCODE()
  451.     StandardWarning(Warn:RIDeleteError,'%CurrentPrimary')
  452.   #IF(%LogoutDesired)
  453.     ROLLBACK
  454.   #ENDIF
  455.     DO RICloseFiles
  456.     RETURN(1)
  457.   ELSE
  458.   #IF(%LogoutDesired)
  459.     COMMIT
  460.   #ENDIF
  461.     DO RICloseFiles
  462.     RETURN(0)
  463.   END
  464. !----------------------------------------------------------------------
  465. RICloseFiles ROUTINE
  466.   #FOR(%DeleteAttachedFile)
  467.   #INSERT(%FileControlCloseFile,%DeleteAttachedFile)
  468.   #ENDFOR
  469.   EXIT
  470. #!----------------------------------------------------------------------
  471. #GROUP(%RIWriteSecondaryUpdateFunction,%CurrentPrimary,%CurrentSecondary)
  472. #DECLARE(%RIParameters)
  473. #DECLARE(%ChangedField),MULTI
  474. #DECLARE(%ChangedFieldLink,%ChangedField)
  475. #DECLARE(%ElementCount)
  476. #DECLARE(%ProcessedElements)
  477. #DECLARE(%UpdateRequired)
  478. #FIX(%File,%CurrentSecondary)
  479. #FIX(%Relation,%CurrentPrimary)
  480. #FIX(%Key,%FileKey)
  481. #SET(%RIParameters,%Null)
  482. #SET(%ElementCount,0)
  483. #FOR(%RelationKeyField),WHERE(%RelationKeyField AND %RelationKeyFieldLink)
  484.   #SET(%ElementCount,%ElementCount+1)
  485.   #SET(%RIParameters,%RIParameters & 'Sav:' & %RelationKeyField & ',')
  486.   #ADD(%ChangedField,%RelationKeyFieldLink)
  487.   #SET(%ChangedFieldLink,'Sav:' & %RelationKeyField)
  488. #ENDFOR
  489. #SET(%RIParameters,SUB(%RIParameters,1,LEN(%RIParameters)-1))
  490. #MESSAGE('Generating RIUpdate:' & %File & ':' & %Relation, 3)
  491. !--------------------------------------------------
  492. RIUpdate:%Relation:%File FUNCTION
  493.  
  494.     CODE
  495.     CLEAR(%FilePrefix:Record,0)
  496.     #FOR(%RelationKeyField)
  497.       #IF(%RelationKeyField)
  498.     %RelationKeyFieldLink = Sav:%RelationKeyField
  499.       #ELSE
  500.         #FOR(%KeyField)
  501.           #IF(%KeyField=%RelationKeyFieldLink)
  502.             #IF(%KeyFieldSequence = 'ASCENDING')
  503.     CLEAR(%RelationKeyFieldLink,-1)
  504.             #ELSE
  505.     CLEAR(%RelationKeyFieldLink,1)
  506.             #ENDIF
  507.             #BREAK
  508.           #ENDIF
  509.         #ENDFOR
  510.       #ENDIF
  511.     #ENDFOR
  512.     SET(%FileKey,%FileKey)
  513.     LOOP
  514.       NEXT(%File)
  515.       IF ERRORCODE()
  516.         IF ERRORCODE() = BadRecErr
  517.           RETURN(0)
  518.         ELSE
  519.           StandardWarning(Warn:RecordFetchError,'%File')
  520.           RETURN(1)
  521.         END
  522.       END
  523.     #SET(%ProcessedElements,0)
  524.     #FOR(%RelationKeyField),WHERE(%RelationKeyField AND %RelationKeyFieldLink)
  525.       #SET(%ProcessedElements,%ProcessedElements+1)
  526.       #IF(%ElementCount=1)
  527.       IF %RelationKeyFieldLink <> Sav:%RelationKeyField
  528.       #ELSIF(%ProcessedElements = 1)
  529.       IF %RelationKeyFieldLink <> Sav:%RelationKeyField |
  530.       #ELSIF(%ProcessedElements = %ElementCount)
  531.       OR %RelationKeyFieldLink <> Sav:%RelationKeyField
  532.       #ELSE
  533.       OR %RelationKeyFieldLink <> Sav:%RelationKeyField |
  534.       #ENDIF
  535.     #ENDFOR
  536.         RETURN(0)
  537.       END
  538.     #IF(%RelationConstraintUpdate='RESTRICT')
  539.       IF StandardWarning(Warn:RestrictUpdate,'%CurrentSecondary')
  540.       #FOR(%RelationKeyField),WHERE(%RelationKeyField AND %RelationKeyFieldLink)
  541.         %RelationKeyField = Sav:%RelationKeyField
  542.       #ENDFOR
  543.         RETURN(1)
  544.       END
  545.     #ELSE
  546.       #FIX(%UpdateRelationPrimary,%CurrentSecondary)
  547.       #IF ( %UpdateRelationPrimary )
  548.       RISnap:%CurrentSecondary
  549.       #ENDIF
  550.       #CASE(%RelationConstraintUpdate)
  551.       #OF('CASCADE')
  552.         #FOR(%RelationKeyField),WHERE(%RelationKeyFieldLink AND %RelationKeyField)
  553.       %RelationKeyFieldLink = %RelationKeyField
  554.         #ENDFOR
  555.       #OF('CLEAR')
  556.         #FOR(%RelationKeyField),WHERE(%RelationKeyFieldLink AND %RelationKeyField)
  557.       CLEAR(%RelationKeyFieldLink)
  558.         #ENDFOR
  559.       #ENDCASE
  560.       #FOR(%UpdateRelationSecondary)
  561.         #SUSPEND
  562.           #SET(%UpdateRequired,%False)
  563.           #FIX(%File,%UpdateRelationPrimary)
  564.           #FIX(%Relation,%UpdateRelationSecondary)
  565.           #SET(%ElementCount,0)
  566.           #FOR(%FileKeyField),WHERE(%FileKeyFieldLink AND %FileKeyField)
  567.             #FIX(%ChangedField,%FileKeyField)
  568.             #IF(%ChangedField)
  569.               #SET(%ElementCount,%ElementCount+1)
  570.             #ENDIF
  571.           #ENDFOR
  572.           #SET(%ProcessedElements,0)
  573.           #FOR(%FileKeyField),WHERE(%FileKeyFieldLink AND %FileKeyField)
  574.             #FIX(%ChangedField,%FileKeyField)
  575.             #IF(%ChangedField)
  576.               #SET(%ProcessedElements,%ProcessedElements+1)
  577.               #IF(%ElementCount=1)
  578.       IF %ChangedField <> %ChangedFieldLink
  579.               #ELSIF(%ProcessedElements=1)
  580.       IF %ChangedField <> %ChangedFieldLink |
  581.               #ELSIF(%ProcessedElements=%ElementCount)
  582.       OR %ChangedField <> %ChangedFieldLink
  583.               #ELSE
  584.       OR %ChangedField <> %ChangedFieldLink |
  585.               #ENDIF
  586.             #ENDIF
  587.           #ENDFOR
  588.           #SET(%ElementCount,%Null)
  589.         #?IF RIUpdate:%File:%Relation()
  590.           #FIX(%File,%CurrentSecondary)
  591.           #FIX(%Relation,%CurrentPrimary)
  592.           #FOR(%RelationKeyField)
  593.             #IF(%RelationKeyField)
  594.           #?%RelationKeyField = %RelationKeyFieldLink
  595.             #ENDIF
  596.           #ENDFOR
  597.           #?RETURN(1)
  598.         #?END
  599.       #?END
  600.         #RESUME
  601.       #ENDFOR
  602.       PUT(%CurrentSecondary)
  603.       IF ERRORCODE()
  604.         IF StandardWarning(Warn:RIUpdateError,'%CurrentSecondary')
  605.           RETURN(1)
  606.         END
  607.       END
  608.     #ENDIF
  609.     END
  610. #!----------------------------------------------------------------------
  611. #GROUP(%RIWriteSecondaryDeleteFunction,%CurrentPrimary,%CurrentSecondary)
  612. #DECLARE(%ElementCount)
  613. #DECLARE(%ProcessedElements)
  614. #DECLARE(%ChangedField),MULTI
  615. #DECLARE(%RIParameters)
  616. #DECLARE(%UpdateRequired)
  617. #FIX(%File,%CurrentSecondary)
  618. #FIX(%Relation,%CurrentPrimary)
  619. #FIX(%Key,%FileKey)
  620. #FOR(%RelationKeyField),WHERE(%RelationKeyField)
  621.   #SET(%ElementCount,%ElementCount+1)
  622.   #ADD(%ChangedField,%RelationKeyFieldLink)
  623. #ENDFOR
  624.  
  625. #MESSAGE('Generating RIDelete:' & %File & ':' & %Relation, 3)
  626. !--------------------------------------------------
  627. RIDelete:%Relation:%File FUNCTION
  628.     CODE
  629.     CLEAR(%FilePrefix:Record,0)
  630.     #FOR(%RelationKeyField)
  631.       #IF(%RelationKeyField)
  632.     %RelationKeyFieldLink = %RelationKeyField
  633.       #ELSE
  634.         #FOR(%KeyField)
  635.           #IF(%KeyField=%RelationKeyFieldLink)
  636.             #IF(%KeyFieldSequence = 'ASCENDING')
  637.     CLEAR(%RelationKeyFieldLink,-1)
  638.             #ELSE
  639.     CLEAR(%RelationKeyFieldLink,1)
  640.             #ENDIF
  641.             #BREAK
  642.           #ENDIF
  643.         #ENDFOR
  644.       #ENDIF
  645.     #ENDFOR
  646.     SET(%FileKey,%FileKey)
  647.     LOOP
  648.       NEXT(%File)
  649.       IF ERRORCODE()
  650.         IF ERRORCODE() = BadRecErr
  651.           RETURN(0)
  652.         ELSE
  653.           StandardWarning(Warn:RecordFetchError,'%File')
  654.           RETURN(1)
  655.         END
  656.       END
  657.     #SET(%ProcessedElements,0)
  658.     #FOR(%RelationKeyField),WHERE(%RelationKeyField AND %RelationKeyFieldLink)
  659.       #SET(%ProcessedElements,%ProcessedElements+1)
  660.       #IF(%ElementCount=1)
  661.       IF %RelationKeyField <> %RelationKeyFieldLink
  662.       #ELSIF(%ProcessedElements = 1)
  663.       IF %RelationKeyField <> %RelationKeyFieldLink |
  664.       #ELSIF(%ElementCount = %ProcessedElements)
  665.       OR %RelationKeyField <> %RelationKeyFieldLink
  666.       #ELSE
  667.       OR %RelationKeyField <> %RelationKeyFieldLink |
  668.       #ENDIF
  669.     #ENDFOR
  670.         RETURN(0)
  671.       END
  672.     #CASE(%RelationConstraintDelete)
  673.     #OF('CASCADE')
  674.       #FIX(%DeleteRelationPrimary,%CurrentSecondary)
  675.       #FOR(%DeleteRelationSecondary)
  676.       IF RIDelete:%DeleteRelationPrimary:%DeleteRelationSecondary()
  677.         RETURN(1)
  678.       END
  679.       #ENDFOR
  680.       DELETE(%CurrentSecondary)
  681.       IF ERRORCODE()
  682.         IF StandardWarning(Warn:RIDeleteError,'%CurrentSecondary')
  683.           RETURN(1)
  684.         END
  685.       END
  686.     #OF('CLEAR')
  687.       #FIX(%UpdateRelationPrimary,%CurrentSecondary)
  688.       #IF(ITEMS(%UpdateRelationSecondary))
  689.       RISnap:%CurrentSecondary
  690.       #ENDIF
  691.       #FOR(%RelationKeyField),WHERE(%RelationKeyField AND %RelationKeyFieldLink)
  692.       CLEAR(%RelationKeyFieldLink)
  693.       #ENDFOR
  694.       #FOR(%UpdateRelationSecondary)
  695.         #SUSPEND
  696.           #SET(%UpdateRequired,%False)
  697.           #FIX(%File,%UpdateRelationPrimary)
  698.           #FIX(%Relation,%UpdateRelationSecondary)
  699.           #SET(%ElementCount,0)
  700.           #FOR(%FileKeyField),WHERE(%FileKeyFieldLink)
  701.             #SET(%ElementCount,%ElementCount+1)
  702.           #ENDFOR
  703.           #SET(%ProcessedElements,0)
  704.           #FOR(%FileKeyField),WHERE(%FileKeyFieldLink)
  705.             #SET(%ProcessedElements,%ProcessedElements+1)
  706.             #FIX(%ChangedField,%FileKeyFieldLink)
  707.             #IF(%ChangedField)
  708.               #RELEASE
  709.             #ENDIF
  710.             #IF(%ElementCount=1)
  711.       #?IF %FileKeyField <> %FileKeyFieldLink
  712.             #ELSIF(%ProcessedElements=1)
  713.       #?IF %FileKeyField <> %FileKeyFieldLink |
  714.             #ELSIF(%ProcessedElements=%ElementCount)
  715.       #?OR %FileKeyField <> %FileKeyFieldLink
  716.             #ELSE
  717.       #?OR %FileKeyField <> %FileKeyFieldLink |
  718.             #ENDIF
  719.           #ENDFOR
  720.           #SET(%ElementCount,%Null)
  721.         #?IF RIUpdate:%CurrentPrimary:%CurrentSecondary()
  722.           #?RETURN(1)
  723.         #?END
  724.       #?END
  725.         #RESUME
  726.       #ENDFOR
  727.       PUT(%CurrentSecondary)
  728.     #OF('RESTRICT')
  729.       IF StandardWarning(Warn:RestrictDelete,'%CurrentSecondary')
  730.         RETURN(1)
  731.       END
  732.     #ENDCASE
  733.     END